<?php
namespace app\asmpasync\service;


use app\common\model\learn_data\HostLearnDataModel;


use think\Db;

class Netfilter
{
    public $classDescription = 'NetFilter服务';//模块描述
    public $actionDescription = '';//操作描述

    /**
     * @name: 防火墙初始化 TODO 当前无此命令
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-29 14:47:32
     */
    public function FirewallInit ()
    {
        $this->actionDescription = '防火墙初始化';
        $FirewallInit = new \Netfilter\FirewallInit();
        $FirewallInit->setEnable(true);

        return $FirewallInit;
    }

    /**
     * @name:默认规则 TODO 当前无此命令
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-12-17 17:02:28
     */
    public function safeRules($host_id, $ruleData)
    {
        $this->actionDescription = '默认规则';
        
        $rules = array_map(function ($v){
            return $v['status'] ? $v['content'] : preg_replace([
                '/iptables -A/i',
                '/netsh advfirewall firewall add rule name="(\w+)"  dir=\w+ action=allow\s+protocol=\w+/i',
                '/New-NetFirewallRule -DisplayName "(\w+)" -Direction \w+ -Action \w+ -protocol \w+/i'
            ],[
                'iptables -D',
                'netsh advfirewall firewall delete name="$1"',
                'remove-NetFirewallRule -DisplayName "$1"'
            ], $v['content']);
        }, $ruleData);
        $return = $this->processRules($rules, true);

        return $return;
    }

    /**
     * @name:初始化默认规则 TODO 当前无此命令
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-12-17 17:02:28
     */
    public function safeRulesInit ($host_id)
    {
        $ruleData = Db::name('NetfilterSafeRule')->field('content,status')->where('host_id', $host_id)->select();
        $return = $this->safeRules($host_id, $ruleData);

        return $return;
    }
    
    /**
     * @name: 防火墙配置 TODO 完成
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-29 14:47:51
     */
    public function FirewallConfig ($host_id)
    {
        $this->actionDescription = '防火墙配置';
        $firewallStatus = $this->processFirewallConfig($host_id);
        $FirewallConfig = new \Netfilter\FirewallConfig();
        $FirewallConfig->setEnable($firewallStatus[0]);
        $FirewallConfig->setOut($firewallStatus[1]);
        $FirewallConfig->setIn($firewallStatus[2]);
        return $FirewallConfig;
    }

    /**
     * @name: 处理ip
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-29 16:38:35
     */
    private function processFirewallConfig ($host_id)
    {
        $firewall = Db::name('HostLearnConfig')->field('firewall')->where('host_id', $host_id)->value('firewall');
        $data = str_split($firewall, 1);
        $return = array_map(function($v){
            return $v ? true : false;
        }, $data);

        return $return;
    }

    /**
     * @name: 防火墙日志状态 TODO 完成
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-29 14:48:13
     */
    public function FirewallLogStatus ($host_id)
    {
        $this->actionDescription = '防火墙日志状态配置';
        $logStatus = Db::name('HostLearnConfig')->field('log_status')->where('host_id', $host_id)->value('log_status');
        $status = $logStatus ? true : false;
        $FirewallLogStatus = new \Netfilter\FirewallLogStatus();
        $FirewallLogStatus->setEnable($status);

        return $FirewallLogStatus;
    }

    /**
     * @name: 学习配置 TODO 已完成
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-29 14:48:35
     */
    public function Study ($host_id)
    {
        $this->actionDescription = '学习设置配置';
        $studyConfig = Db::name('HostLearnConfig')->field('etime,have_mac_addr,model')->where('host_id', $host_id)->find();
        $Study = new \Netfilter\Study();
        $remainTime = $studyConfig['etime'] - time();
        if ($remainTime > 0)
        {
            //学习模式 1累计学习模式 2全新学习模式
            if($studyConfig['model'] == 2)
            {
                //操作子库中的学习数据
                $learnModel = new HostLearnDataModel();
                $learnModel->setHostId($host_id);
                $learnModel->where('host_id', $host_id)->delete();

            }
        }
        else
        {
            $remainTime = 0;
        }
        $Study->setTime($remainTime);
        $mark = $studyConfig['have_mac_addr'] ? true : false;
        $Study->setMark($mark);

        return $Study;
    }

    /**
     * @name: 规则处理
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-29 14:48:59
     */
    private function Rule($rule, $is_default = false)
    {
        $Rule = new \Netfilter\Rule();
        $Rule->setCmd($rule);
        $Rule->setDefault($is_default);
        
        return $Rule;
    }

    /**
     * @name: 添加规则 TODO 当前无此命令
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-29 14:59:17
     */
    public function addRules ($host_id, $ruleData, $batch = false)
    {
        $this->actionDescription = '添加规则';
        $ruleData = array_map(function($v){
            $v['status'] = 1;
            return $v;
        }, $ruleData);

        $Rule = new \app\common\netfilter\Rule($host_id);
        $data = $Rule->firewallRule($ruleData, $batch);
        $return = $this->processRules($data);
        
        return $return;
        
    }

    /**
     * @name: 删除规则  TODO 当前无此命令
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-12-12 14:47:31
     */
    public function delRules ($host_id, $ruleData)
    {
        $this->actionDescription = '删除规则';
        $ruleData = array_map(function($v){
            $v['status'] = 3;
            return $v;
        },$ruleData);

        $Rule = new \app\common\netfilter\Rule($host_id);
        $data = $Rule->firewallRule($ruleData);
        $return = $this->processRules($data);

        return $return;
    }

    /**
     * @name: 修改规则 TODO 当前无此命令
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-12-12 15:03:52
     */
    public function modifyRules ($host_id, $newRule, $oldRule)
    {
        $this->actionDescription = '修改规则';
        $ruleData = array_map(function($v){
            $v['status'] = 3;
            return $v;
        },$oldRule);
        $newRule['status'] = 1;
        $ruleData[] = $newRule;
        $Rule = new \app\common\netfilter\Rule($host_id);
        $data = $Rule->firewallRule($ruleData);
        $return = $this->processRules($data);

        return $return;
    }

    /**
     * @name: 处理规则
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-12-12 14:54:23
     */
    private function processRules ($data, $is_default = false)
    {
        $return = [];
        foreach ($data as $v)
        {
            $return[] = $this->Rule($v, $is_default);
        }
        $Rules = new \Netfilter\Rules();
        $Rules->setCmds($return);
        $Rules->setOut(false);//只是为了填充数据 不可删除 
        $Rules->setIn(false);//只是为了填充数据 不可删除 
        return $Rules;
    }
}